package com.bwda.dsrs.filecenter.service.impl;


import com.bwda.dsrs.base.centerbase.BaseContextHandler;
import com.bwda.dsrs.base.util.CopyUtil;
import com.bwda.dsrs.filecenter.api.OrgServiceApi;
import com.bwda.dsrs.filecenter.api.clientappversion.org.OrgForm;
import com.bwda.dsrs.filecenter.api.clientappversion.user.UserVo;
import com.bwda.dsrs.filecenter.api.log.LogTemplate;
import com.bwda.dsrs.filecenter.aspect.LogTypeEnum;
import com.bwda.dsrs.filecenter.domain.BusinessConstants;
import com.bwda.dsrs.filecenter.domain.condition.userlog.UserLogCondition;
import com.bwda.dsrs.filecenter.domain.exception.BusinessServiceException;
import com.bwda.dsrs.filecenter.domain.form.userlog.UserLogTreeFrom;
import com.bwda.dsrs.filecenter.domain.po.userlog.RetroSpectPo;
import com.bwda.dsrs.filecenter.domain.po.userlog.UserLogPo;
import com.bwda.dsrs.filecenter.mapper.dsrs.BusUserLogMapper;
import com.bwda.dsrs.filecenter.service.BusUserLogService;
import com.bwda.dsrs.util.LogServiceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 查询用户日志
 *
 * @author liangjianyong
 * @date 2019/5/20
 */
@Service
public class BusUserLogServiceImpl extends BaseServiceImpl<UserLogPo, UserLogCondition, BusUserLogMapper> implements
        BusUserLogService {
    private final Logger logger = LoggerFactory.getLogger(BusUserLogServiceImpl.class);


    @Autowired
    private LogServiceUtil logServiceUtil;


    @Autowired
    private OrgServiceApi orgServiceApi;

    /**
     * 批量添加
     *
     * @param userLogs
     * @return
     */
    @Override
    public void insertBatch(List<UserLogPo> userLogs) {
        this.getMapper().insertBatch(userLogs);
    }

    /**
     * 插入日志
     *
     * @param fileId       文件id
     * @param fileName     文件名称
     * @param fileSize     文件大小
     * @param originFileId 原始文件id
     * @param operateName  操作描述
     * @param operateType  操作类型
     * @param msg          执行结果
     * @param rescode      执行状态
     * @return
     */
    @Override
    public void insertUserLog(Integer fileId, String fileName, Integer fileSize, Integer originFileId, String operateName, String operateType, String msg, Integer rescode, String targetObject) {
        //记录日志信息
        LogTemplate logTemplate = new LogTemplate();
        logTemplate.setServiceId("consumer");
        logTemplate.setId(2);
        logTemplate.setHandleType("toDB");
        //	UserLogPo userLogPo = new UserLogPo();
        com.bwda.dsrs.domain.po.userlog.UserLogPo userLogPo = new com.bwda.dsrs.domain.po.userlog.UserLogPo();
        //获取用户名
        userLogPo.setLoginToken(BaseContextHandler.getAuthorization());
        userLogPo.setUserCode(BaseContextHandler.getUserCode());
        userLogPo.setUserName(BaseContextHandler.getUserName());
        Boolean flag = false;
        //true 浙江移动组织
        if (flag) {
            try {
                UserVo vo = orgServiceApi.queryUserByUserCode(BaseContextHandler.getUserCode());
                String zjOrgName = getOrgStr(vo.getOrgId(), "");
                userLogPo.setOrgName(zjOrgName);
            } catch (BusinessServiceException e) {
                e.printStackTrace();
            }
        } else {
            userLogPo.setOrgName(BaseContextHandler.getOrgName());
        }
        userLogPo.setCreateTime(new Date());
        String ipAddr = BaseContextHandler.getIpAddr();
        userLogPo.setIpAddr(ipAddr);
        userLogPo.setFileId(String.valueOf(fileId));
        userLogPo.setFileName(fileName);
        userLogPo.setFileSize(String.valueOf(fileSize));
        userLogPo.setOriginFileId(String.valueOf(originFileId));
        //操作描述
        userLogPo.setOperateContent(operateName);
        //操作类型
        userLogPo.setOperateType(operateType);
        userLogPo.setExceptionMsg(msg);
        //请求结果
        userLogPo.setStatus(rescode);
        userLogPo.setTargetObject(targetObject);
        logTemplate.setUserLogPo(userLogPo);
        try {
            com.bwda.dsrs.domain.po.serverslog.LogTemplate logTemplate1 = getConditionByQueryForm(logTemplate);
            logServiceUtil.handleLogServiceUtil(logTemplate1);
            logger.info("用户系统日志信息sucess！");
        } catch (Exception e) {
            logger.error("用户系统日志信息失败！");
        }
    }

    /**
     * 插入日志
     *
     * @param fileId       文件id
     * @param fileName     文件名称
     * @param fileSize     文件大小
     * @param originFileId 原始文件id
     * @param operateName  操作描述
     * @param operateType  操作类型
     * @param msg          执行结果
     * @param rescode      执行状态
     * @return
     */
    @Override
    public void insertUserLogNoToken(String userCode, String userName, String orgName, Integer fileId, String fileName, Integer fileSize, Integer originFileId, String operateName, String operateType, String msg, Integer rescode, String targetObject) {
        //记录日志信息
        LogTemplate logTemplate = new LogTemplate();
        logTemplate.setServiceId("consumer");
        logTemplate.setId(2);
        logTemplate.setHandleType("toDB");
        //	UserLogPo userLogPo = new UserLogPo();
        com.bwda.dsrs.domain.po.userlog.UserLogPo userLogPo = new com.bwda.dsrs.domain.po.userlog.UserLogPo();
        //获取用户名
        userLogPo.setUserCode(userCode);
        userLogPo.setUserName(userName);
        Boolean flag = false;
        //true 浙江移动组织
        if (flag) {
            try {
                UserVo vo = orgServiceApi.queryUserByUserCode(userCode);
                String zjOrgName = getOrgStr(vo.getOrgId(), "");
                userLogPo.setOrgName(zjOrgName);
            } catch (BusinessServiceException e) {
                e.printStackTrace();
            }
        } else {
            userLogPo.setOrgName(orgName);
        }
        userLogPo.setCreateTime(new Date());
        userLogPo.setFileId(String.valueOf(fileId));
        userLogPo.setFileName(fileName);
        userLogPo.setFileSize(String.valueOf(fileSize));
        userLogPo.setOriginFileId(String.valueOf(originFileId));
        //操作描述
        userLogPo.setOperateContent(operateName);
        //操作类型
        userLogPo.setOperateType(operateType);
        userLogPo.setExceptionMsg(msg);
        //请求结果
        userLogPo.setStatus(rescode);
        userLogPo.setTargetObject(targetObject);
        logTemplate.setUserLogPo(userLogPo);
        try {
            com.bwda.dsrs.domain.po.serverslog.LogTemplate logTemplate1 = getConditionByQueryForm(logTemplate);
            logServiceUtil.handleLogServiceUtil(logTemplate1);
        } catch (Exception e) {
            logger.info("用户系统日志信息失败！");
        }
    }

    @Override
    public List<UserLogTreeFrom> queryListForSy(int fileId, int type) {
        List<UserLogTreeFrom> list = new ArrayList<UserLogTreeFrom>();
        String typeCode = "";
        List<UserLogTreeFrom> treeList = null;
        try {
            //来源是个人文件
            if (type == BusinessConstants.NumberConstant.ZERO) {
                UserLogCondition condition = new UserLogCondition();
                condition.setFileId(String.valueOf(fileId));
                condition.setOperateType(LogTypeEnum.UPLOAD.value());
                List<UserLogPo> list1 = this.getMapper().selectList(condition);
                if (list1 == null || list1.size() == 0) {
                    typeCode = LogTypeEnum.COPY.value();
                    list = this.getMapper().selectFile(String.valueOf(fileId));
                    treeList = listGetTreeForLz(list, fileId, typeCode);
                } else {
                    typeCode = LogTypeEnum.UPLOAD.value();
                    list = this.getMapper().selectOrigin(String.valueOf(fileId));
                    treeList = listGetTree(list, fileId, typeCode);
                }
            } else
                //来源是外接服务器移动
                if (type == BusinessConstants.NumberConstant.FIVE) {
                    UserLogCondition condition = new UserLogCondition();
                    condition.setFileId(String.valueOf(fileId));
                    condition.setOperateType(LogTypeEnum.MOVE.value());
                    List<UserLogPo> list1 = this.getMapper().selectList(condition);
                    if (list1 == null || list1.size() == 0) {
                        typeCode = LogTypeEnum.SYNC.value();
                    } else {
                        typeCode = LogTypeEnum.MOVE.value();
                    }
                    list = this.getMapper().selectOrigin(String.valueOf(fileId));
                    treeList = listGetTree(list, fileId, typeCode);
                } else
                    //来源是流转
                    if (type == BusinessConstants.NumberConstant.TWO) {
                        typeCode = LogTypeEnum.FLOW_SUCCESS.value();
                        list = this.getMapper().selectFile(String.valueOf(fileId));
                        treeList = listGetTreeForLz(list, fileId, typeCode);

                    } else {
                        throw new BusinessServiceException("该文件来源暂不支持");
                    }
            logger.info("操作成功");
        } catch (BusinessServiceException e) {
            logger.error("文件信息错误");
        }
        return treeList;
    }

    /**
     * 递归将数据变为想要的类型
     *
     * @param list
     * @return
     */
    @Override
    public Map queryFkList(List<UserLogTreeFrom> list) {
        Map map = new HashMap(16);
        List<RetroSpectPo> data = new ArrayList<RetroSpectPo>();
        List<RetroSpectPo> links = new ArrayList<RetroSpectPo>();
        if(CollectionUtils.isEmpty(list)){
            return map;
        }

        RetroSpectPo po = new RetroSpectPo();
        po.setName(list.get(0).getId());
        po.setUserName(list.get(0).getUserName());
        data.add(po);
        List<UserLogTreeFrom> list1 = list.get(0).getChildren();
        if (list1 != null && list1.size() != 0) {
            for (int i = 0; i < list1.size(); i++) {
                RetroSpectPo po2 = new RetroSpectPo();
                RetroSpectPo po1 = new RetroSpectPo();
                po2.setName(list1.get(i).getId());
                po2.setUserName(list1.get(i).getUserName());
                po2.setCategory(BusinessConstants.NumberConstant.ONE);
                po1.setSource(Integer.parseInt(list.get(0).getId()));
                po1.setTarget(Integer.parseInt(list1.get(i).getId()));
                po1.setValue(list1.get(i).getOperateType());
                data.add(po2);
                links.add(po1);
                if (LogTypeEnum.FLOW_SUCCESS.value().equals(list1.get(i).getOperateType())) {
                    getNodeTwo(list1.get(i), data, links, list1.get(i).getId());
                }
            }
        }
        for (int k = 0; k < links.size(); k++) {
            links.get(k).setTarget(k + 1);
            String index = links.get(k).getSource().toString();
            links.get(k).setSource(returnIndex(data, index));
        }
        for (int i = 0; i < data.size(); i++) {
            String name = data.get(i).getUserName();
            data.get(i).setId(data.get(i).getName());
            data.get(i).setName(name);
        }
        map.put("data", data);
        map.put("links", links);
        return map;
    }

    @Override
    public List<UserLogPo> selectAll() {
        return this.getMapper().selectAll();
    }

    /**
     * 判断
     *
     * @param list
     * @param index
     * @return
     */
    private Integer returnIndex(List<RetroSpectPo> list, String index) {
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getName().equals(index)) {
                return i;
            }
        }
        return null;
    }

    /**
     * 来源是上传追溯tree
     */
    private List<UserLogTreeFrom> listGetTree(List<UserLogTreeFrom> list, int fileId, String typeCode) throws BusinessServiceException {
        List<UserLogTreeFrom> treeList = new ArrayList<UserLogTreeFrom>();
        if ("".equals(typeCode)) {
            throw new BusinessServiceException("参数错误");
        }

        for (UserLogTreeFrom tree : list) {
            //找到根 判断第一级上传
            if (tree.getFileId() == fileId && typeCode.equals(tree.getOperateType())) {
                treeList.add(tree);
                //找到第二层
                for (UserLogTreeFrom treeNode : list) {
                    if (treeNode.getOriginFileId() == fileId && !typeCode.equals(treeNode.getOperateType())) {
                        if (tree.getChildren() == null) {
                            tree.setChildren(new ArrayList<UserLogTreeFrom>());
                        }
                        if (LogTypeEnum.FLOW_SUCCESS.value().equals(treeNode.getOperateType())) {
                            UserLogTreeFrom userLogTreeFrom = getNode(treeNode);
                        }
                        tree.getChildren().add(treeNode);
                    }
                }
            }
        }
        return treeList;
    }

    /**
     * 来源是流转追溯tree
     */
    private List<UserLogTreeFrom> listGetTreeForLz(List<UserLogTreeFrom> list, int fileId, String typeCode) throws BusinessServiceException {
        List<UserLogTreeFrom> treeList = new ArrayList<UserLogTreeFrom>();
        if ("".equals(typeCode)) {
            throw new BusinessServiceException("参数错误");
        }
        for (UserLogTreeFrom tree : list) {
            //找到根 判断第一级是流转
            if (tree.getFileId() == fileId && typeCode.equals(tree.getOperateType())) {
                treeList.add(tree);
                list = this.getMapper().selectOrigin(String.valueOf(fileId));
                //找到第二层
                for (UserLogTreeFrom treeNode : list) {
                    if (tree.getChildren() == null) {
                        tree.setChildren(new ArrayList<UserLogTreeFrom>());
                    }
                    if (LogTypeEnum.FLOW_SUCCESS.value().equals(treeNode.getOperateType())) {
                        UserLogTreeFrom userLogTreeFrom = getNode(treeNode);
                    }
                    tree.getChildren().add(treeNode);
                }
            }
        }
        return treeList;
    }


    public UserLogTreeFrom getNode(UserLogTreeFrom treeFromList) {
        List<UserLogTreeFrom> list = this.getMapper().selectOrigin(treeFromList.getFileId().toString());
        for (int i = 0; i < list.size(); i++) {
            if (list != null && list.size() != 0) {
                if (treeFromList.getChildren() == null) {
                    treeFromList.setChildren(new ArrayList<UserLogTreeFrom>());
                }
                treeFromList.getChildren().add(list.get(i));
                if (LogTypeEnum.FLOW_SUCCESS.value().equals(list.get(i).getOperateType())) {
                    getNode(list.get(i));
                }
            }
        }
        return treeFromList;
    }

    public void getNodeTwo(UserLogTreeFrom treeFromList, List<RetroSpectPo> data, List<RetroSpectPo> links, String id) {
        List<UserLogTreeFrom> list = this.getMapper().selectOrigin(treeFromList.getFileId().toString());
        for (int i = 0; i < list.size(); i++) {
            if (list != null && list.size() != 0) {
                RetroSpectPo po = new RetroSpectPo();
                RetroSpectPo po1 = new RetroSpectPo();
                po.setName(list.get(i).getId());
                po.setCategory(BusinessConstants.NumberConstant.ONE);
                po.setUserName(list.get(i).getUserName());
                po1.setSource(Integer.parseInt(id));
                po1.setTarget(Integer.parseInt(list.get(i).getId()));
                po1.setValue(list.get(i).getOperateType());
                data.add(po);
                links.add(po1);
                if (LogTypeEnum.FLOW_SUCCESS.value().equals(list.get(i).getOperateType())) {
                    getNodeTwo(list.get(i), data, links, list.get(i).getId());
                }
            }
        }
    }

    private String getOrgStr(Integer orgId, String orgName) {
        OrgForm orgForm = orgServiceApi.queryByIdOrg(orgId);
        if (orgForm == null) {
            return orgName;
        }
        if (com.bwda.dsrs.constants.Constants.ONE_STRING.equals(orgForm.getId())) {
            orgName = orgForm.getOrgName() + orgName;
        }
        if (!com.bwda.dsrs.constants.Constants.ONE_STRING.equals(orgForm.getId())) {
            orgName = "/" + orgForm.getOrgName() + orgName;
            orgName = getOrgStr(orgForm.getParentId(), orgName);
        }
        return orgName;
    }


    /**
     * com.bwda.dsrs.systemservice.api.LogTemplate转换为com.bwda.dsrs.domain.po.serverslog.LogTemplate
     *
     * @param form
     * @return
     */
    private com.bwda.dsrs.domain.po.serverslog.LogTemplate getConditionByQueryForm(LogTemplate form) {
        com.bwda.dsrs.domain.po.serverslog.LogTemplate condition = CopyUtil.transfer(form, com.bwda.dsrs.domain.po.serverslog.LogTemplate.class);
        return condition;
    }

}